// JavaScript Document

/*
	MUDAR ESQUMA DE SELEÇÃO de "('.container_perg').children('.container_altern')", pois ao
	agrupar perguntas em forma de tabela perde a estrutura padrão pai -> descendente
 */

$(function(){
	
	
	$.ajaxSetup({
		
		error: function(xhr,err) 
		{		
			$('#dialog-error').html('<p>Ops! Ocorreu um Erro no método "'+currentCallAjax+'": <br><br>' + xhr.responseText + '</p><br>')
							  .dialog({
								  close: function(event , ui) {
									  $(this).remove();
								  },
								  title: "Error: " + err,
								  width: 340
							  });
		}
	});
	
	
	

/* FUNÇÕES
----------------------------------------------------------*/
	
	function estiliza() {
		
		$containersAltern = $('.container_altern');
		
		// varrendo todos os spans '.container_altern'
		$containersAltern.each(function (i) {
			
			var len_aux 	 = 0;
			var $descAlterns = $(this).find('.descAltern');

			// a classe '.descAltern' é inserida somente aos labels de descrição 
			// da alternativa que antecedem um elemento input text.
			if ( $descAlterns.length > 0 )
			{
				$descAlterns.each(function() {
					
					len = $(this).text().length;
					if (len > len_aux)
					{
						len_aux = len;
						$descAlterns.closest('.container_altern')
									.find('.descAltern')
									.css({
										width: function(index, value) {
											
											return ( parseInt( len * 9) );
										},
										display: 'block',
										float: 	 'left'
									});
					}
					
				});
				
			}
			
      	});
	}
	
	function executaAcao(acao, $alternativa) 
	{
		
		switch (acao)
		{
			case "PROX_Q":
				$elementFoco = $alternativa.closest('.container_perg').next().children('.container_altern').children().first();

				// Verificando se o 1ª elemento é um label
				if ( $elementFoco[0].nodeName == 'LABEL')
					$elementFoco = $elementFoco.next();
					
				$elementFoco.focus();
				chamouAcao_Altern = true;
			break;
			
			case "Q":

				// Verificando se a ação é do tipo "Possui Valor" (campos texto)
				if ( $alternativa[0].tagName == 'INPUT' && $alternativa[0].type == "text")
				{
					valorAcao = $alternativa.siblings('input[name="valorAcao"]').val();
					
					if ($alternativa.val() != valorAcao)
					{
						/* Caso possua a ação seValor, mas o valor não corresponde ao 
						 * valor pré-definido, faz com que o método não prossiga.
						 */
						return false;
					}
				} 
				
				// target conterá algo como: "span#1.15", ou seja, o ID do span que representa o nº da questão 1.15
				numQuestAlvo = $alternativa.siblings('input[name="descAcao"]').val().replace('.','_');
				target 		 = 'span#' + numQuestAlvo;
				$elementFoco = $alternativa.closest('.container_perg').siblings()
										   .find(target).closest('.container_perg')
										   .children('.container_altern').children().first();
//				$elementFoco =  $(target).closest('.container_perg').children('.container_altern').children().first();

				// Verificando se o 1ª elemento é um label
				if ( $elementFoco[0].nodeName == 'LABEL')
				{
					// Verificando se o elementFoco (LABEL) possui filho(s),
					// como é o caso dos elementos do tipo 'radio' e 'checkbox'
					if ($elementFoco.children().length > 0)
					{
						// Caso o 1º filho seja do tipo 'INPUT' (como, 
						// por exemplo, 'radio' e 'checkbox')
						if ( $elementFoco.children().first()[0].nodeName == 'INPUT' )
						{
							$elementFoco = $elementFoco.children().first();
						} else
						{
							$elementFoco = $elementFoco.next();
						}
						
					// Caso o elementFoco (LABEL) não possua filho(s), seleciona-se
					// como foco o elemento posterior a ele (que provavelmente é 
					// um input 'TEXT'
					} else 
					{
						$elementFoco = $elementFoco.next();
					}
				}
				
				$elementFoco.focus();
				chamouAcao_Altern = true;
					
				
				
			break;
			
			case "MSG":
			break;
			
			case "DE_ATE":
				
				
			
			break;
			case "S":
				alert('Vá para a Seção ' + idTarget);
			break;
		}

	}
	
	function pergAtiva($child)
	{
		if ( ! chamouAcao_Altern )
		{
			$('.pergunta').removeClass('active-perg');
			$child.closest('.container_perg').children('.pergunta').addClass('active-perg');
		}
		
		chamouAcao_Altern = false;
	}
	
	
	function trataVariasResp() 
	{
		$containers_altern = $('input#qtdRespostas[value="V"]').closest('span.container_altern');
		
		$containers_altern.each(function(i) {
			
			htmlContainer = $(this).html();
			
			html  = '<div class="varias_resp">' +
						'<div class="nova_resp">' + 
							htmlContainer + 
						'</div>' + 
						'<div class="botoes_resp">' +
							'<input type="button" name="delResp" value="Remover" />' +
							'<input type="button" name="addResp" value="Adicionar Resposta" /> </br></br>' +
							'<input type="button" name="confirm" value="Confirmar e prosseguir..." />' +
						'</div>' +
					'</div>';
					
			$(this).html(html);
			
			acao = verificaAcao( $(this).find('.alternativa') );
			
			if (acao == "DE_ATE")
			{
				/* Criando a DIV que conterá o grupo de perguntas a serem preenchidas para cada alternativa
				 * que contenha a ação DE_ATE, e atribuindo a DIV criada a variável $grupo_pergs
				 */
				$grupo_pergs = $(this).closest('.container_perg')
									  .after('<div class="grupoPergs" style="display:none;"></div>')
									  .next();
				
				de_ate    = $(this).find('.alternativa').siblings('input[name="descAcao"]').val(); // Algo como: 2.02-2.32
				arr_deAte = de_ate.split('-'); // Algo como: [0]: 2.02, [1]: 2.32
				secao 	  = ( arr_deAte[0].split('.') )[0];
				inicio    = arr_deAte[0];
				fim       = arr_deAte[1];
				
				perg_inici = parseInt( (inicio.split('.'))[1] );
				perg_final = parseInt( (   fim.split('.'))[1] );
				
				/* Percorrendo os números das perguntas a serem preenchidas (DE_ATE) e 
				 * movendo o container_perg para a div .grupo_pergs
				 */
				for (i = perg_inici; i <= perg_final; i++)
				{
					num_perg = i < 10 ? "0" + i : i; // -> if (i < 10) {num_perg = "0" + i } else {num_perg = i }
					
					// Montando o ID do span que contém o número da pergunta ''
					target   = '#' + secao + "_" + num_perg; // Algo como: #2_02
					
					$container_perg = $(target).closest('.container_perg');
					html = 	'<span class="container_perg">' + 
								$container_perg.html() + 
							'</span>';
					
					$grupo_pergs.append( html );
					$container_perg.remove();
				}
			}
			
		});
		
		
		/* VINCULANDO Eventos aos botões criados: */
		
		$('input[name="addResp"]', '.varias_resp .botoes_resp').live({
			
			click: function() {
				
				$ultimaDiv_novaResp = $(this).closest('div.botoes_resp').siblings('div.nova_resp').last();
				$ultimaDiv_novaResp.after('<div class="nova_resp">' + $ultimaDiv_novaResp.html() + '</div>' );
				$(this).closest('div.botoes_resp').siblings('div.nova_resp').last().find('.alternativa').focus();
				
			}
			
		});
		
		$('input[name="delResp"]', '.varias_resp .botoes_resp').live({
			
			click: function() {
				
				$divs_novaResp = $(this).closest('div.botoes_resp').siblings('div.nova_resp');
				
				if ( $divs_novaResp.length > 1  )
				{
					$divs_novaResp.last().remove();
				}
			}
			
		});
		
		$('input[name="confirm"]', '.varias_resp .botoes_resp').live({
			
			click: function() {
				
				$btConfirm = $(this);
				
				vazios = $btConfirm.closest('.container_altern')
								   .find('input[type="text"]')
								   .filter(function() { return $(this).val() == ""; }).length;
				
				if (vazios > 0)
				{
					jAlert('Existem campos vazios para esta pergunta.', 'Atenção');
				} else {
				
					perg = 'Para cada Lote terá que responder uma série de<br>' +
						   'perguntas e só poderá sair após conluí-las. Deseja<br>' +
						   'prosseguir agora?';
						   
					jConfirm(perg, 'Confirmação', function(opc) {
						
						if (opc)
						{
							chamaDialog( $btConfirm );
						}
						
					});
				
				}				
			}
			
		});
		
	}
	
	/* Agrupa perguntas que possuem a mesma Categoria em forma de Tabela
	 */
	function agrupaPergs()
	{
		// Resgata todos os :hidden "categPerg" filhos de "container_perg".
		// Representa o código da Categoria das pergs (caso possuam)
		$categsPerg = $('.categPerg');
		
		if ( $categsPerg.length > 0 )
		{	 
			categ_base = 0;

			$categsPerg.each(function() {
				
				currentCateg = $.trim( $(this).val() );
				
				// Na primeira e, também, toda vez que mudar a categoria,
				// cria uma nova tabela para o agrupamento
				if ( currentCateg != categ_base )
				{
					categ_base = currentCateg;
					
					// Cria a tabela inicialmente vazia
					$table = $('<table class="table_grupoPergs"> <thead></thead> <tbody></tbody> </table>');
					$('#questionario').append( $table );

					// Chama função "getJson" para consultar os dados da Categoria corrente.
					// Após a execução "getJson" chama a funlçao passada "contAgrupaPergs" que tem
					// como parâmetros um objeto json e um array de parâmetros ("paramsFunc" abaixo)
					var paramsFunc = Array($table, "imp_categ");			 
					getJson("categoria", "tabela", currentCateg, "categ", "agrupaPergs()", contAgrupaPergs, paramsFunc);
					
				} 
			});
		}
		
	}
	
	/* ALTERAR forma de inserção da "Categoria" das perguntas, fazendo com que cada CodsPreResp
	 * gere uma nova linha na tabela "Categoria".
	 */
	function contAgrupaPergs(json, arrParams)
	{
		$table = arrParams[0];
		acao   = arrParams[1];
		
		switch(acao.toLowerCase())
		{
			// Imprime no cabeçalho da Tabela a Categoria das perguntas
			case "imp_categ": 
				
				// Adiciona-se na tabela criada o título do agrupamento, ou seja, a descrição da 
				// Categoria das Perguntas
				categ = json.categ;
				$table.find('thead').append('<tr> <th>'+ categ[0].descCateg +'</th> </tr>');
				
				/* Consultando as pré-respostas que fazem parte da Categoria corrente
				 * das perguntas e a Categoria que as pré-respostas fazem parte
				 */
				query_preResps = 	' SELECT  prer.codPreResp, prer.Descricao AS descPreResp, prer.tipo AS tipoPreResp, ' +
									' 		prer.codCategPreResp AS categPreResp, catpr.Descricao AS descCategPreResp   ' +
									' FROM 		 PreResposta  prer ' +
									' INNER JOIN Categoria    cat   ON (prer.codCategPerg    = cat.codCateg) ' +
									' INNER JOIN CategPreResp catpr ON (prer.codCategPreResp = catpr.codCategPreResp) ' +
									' WHERE cat.codCateg = ' + categ[0].codCateg;
				
				
				/* Realiza a consulta das pré-respostas e suas categorias ("getJson") e chama esta 
				 * mesma função "contAgrupaPergs" para continuar a impressão
				 */
				var params = Array($table, "imp_preresps", categ[0].codCateg);
				getJson(query_preResps, "query", "", "preResps", "contAgrupaPergs()", contAgrupaPergs, params);
				
			break;

			case "imp_preresps":
				
				categPerg = arrParams[2];
				
				// Adiciona-se ao thead a "Categoria" das Pré-Respostas.
				preResps = json.preResps;
				$table.find('thead').append('<tr> <th>'+ preResps[0].descCategPreResp +'</th> </tr>');
				
				// Imprime todas as pré-respostas na primeira coluna das linhas do "tbody"
				for (i = 0; i < preResps.length; i++)
				{
					descPreResp = preResps[i].descPreResp;
					
					// Caso a pré resposta consultada seja "", representará um campo 
					// texto para que o usuário informe, como é o caso das pré-respostas
					// "Código das Culturas"
					if ( $.trim(descPreResp) == "" )
					{
						preResp = 	' <tr> 	 ' +
									' 	<td> ' +
									' 		<input type="text"   name="descPreResp" /> ' +
									' 		<input type="hidden" name="codPreResp" ' +
									'			   value="'+ $.trim(preResps[i].codPreResp) +'"  /> ' +
									' 	</td> ' +
									' </tr> 	 ';
					} else 
					{
						preResp = 	' <tr> 	 ' +
									' 	<td> ' +
											descPreResp +
									' 		<input type="hidden" name="codPreResp" ' +
									'			   value="'+ $.trim(preResps[i].codPreResp) +'"  /> ' +
									' 	</td> ' +
									' </tr>   ';
					}
					
					$table.find('tbody').append( preResp );
				}
				
				// Adiciona-se ao cabeçalho da tabela as perguntas que fazem parte do agrupamento
				$containersPerg = $('.categPerg[value="'+ $.trim(categPerg) +'"]').closest('.container_perg');
				$containersPerg.each(function() {
					
					$perg    = $(this);
					$alterns = $(this).find('.container_altern');
					
					$perg.find('.container_altern').remove();
					
					// Setando um estilo padrão
					setDefaultCss(Array($perg, $alterns));
					
					// Inserindo a pergunta no cabeçalho da tabela
					$table.find('thead tr:last-child th:last-child').after('<th></th>');
					$table.find('thead tr:last-child th:last-child').append( $perg );
					
					// Varre todas as linhas do "tbody" para que seja criada uma nova coluna 
					// em cada uma delas com a alternativa referente à pergunta corrente
					$tr_tbody = $table.find('tbody tr');
					$tr_tbody.each(function()
					{
						$(this).find('td:last-child').after('<td></td>');
						$(this).find('td:last-child').append( $alterns );
					});
					
					
				});
				
				// Seta o atribuo "colspan" da coluna da primeira linha 
				// com o número total de colunas (th) existentes
				countCols = $table.find('thead tr:last-child th').length;
				$table.find('thead tr:first-child').children('th').attr('colspan', countCols);
				
				
				
				/*
				
				// Após imprimir as pré-respostas, adiciona-se ao cabeçalho da tabela 
				// as perguntas que fazem parte do agrupamento
				
				$containersPerg = $('.categPerg[value="'+ $.trim(preResps[0].codCategPreResp) +'"]').closest('.container_perg');
				$containersPerg.each(function() {
					
					$perg    = $(this);
					$alterns = $(this).find('.container_altern');
					
					$perg.find('.container_altern').remove();
					
					// Setando um estilo padrão
					setDefaultCss(Array($perg, $alterns));
					
					// Inserindo a pergunta no cabeçalho da tabela
					$table.find('thead tr:last-child th:last-child').after('<th></th>');
					$table.find('thead tr:last-child th:last-child').append( $perg );
					
					// Varrendo as linhas do "tbody" da tabela e inserindo em cada uma
					// as alternativas para a questão
					$table.find('tbody tr').each(function() {
						
						$(this).find('td:last-child').append('<td></td>')
						$(this).find('td:last-child td:last-child').append( $alterns );
						
					});
					
				});
				
				*/
				
			break;
		}
	}
	
	
	function setDefaultCss(elements)
	{
		if ( verificaTipo(elements, "array"))
		{
			for (i = 0; i < elements.length; i++)
			{
				$element = elements[i];
				
				$element.css({
					margin: 	0,
					padding: 	0,
					width: 		'auto',
					height: 	'auto',
					fontFamily:	'"Times New Roman", Times, serif',
					fontSize: 	'14px',
					fontWeight:	'normal'
				});
				
				$element.find('*').css({
					margin: 	0,
					padding: 	0,
					width: 		'auto',
					height: 	'auto',
					fontFamily:	'"Times New Roman", Times, serif',
					fontSize: 	'14px',
					fontWeight:	'normal'
				});
			}
		} else 
		{
			$element = elements;
				
			$element.css({
				margin: 	0,
				padding: 	0,
				width: 		'auto',
				height: 	'auto',
				fontFamily:	'"Times New Roman", Times, serif',
				fontSize: 	'10px',
				fontWeight:	'normal'
			});
			
			$element.find('*').css({
				margin: 	0,
				padding: 	0,
				width: 		'auto',
				height: 	'auto',
				fontFamily:	'"Times New Roman", Times, serif',
				fontSize: 	'10px',
				fontWeight:	'normal'
			});
		}
	}
	
	function verificaTipo(variavel, tipo)
	{
		if (tipo.toLowerCase() == "array")
		{
			return(typeof(variavel.length)=="undefined")?false:true;
		} else 
		{
			return typeof(variavel) == tipo;
		}
	}
	
	function chamaDialog($btConfirm) 
	{
		num_perg = $btConfirm.closest('.container_perg').find('.num_perg').text(); // Algo como 2.02
		$lotes   = $btConfirm.closest('.container_perg').find('input[type="text"]').filter('.alternativa');
		
		html_dialog = 	'<div id="dialog_pergs" class="vinculo_perg['+ num_perg +']">' + 
						
							$btConfirm.closest('.container_perg').next('.grupoPergs').html() + 
							'<div id="infoLotes" style="display:none;" >' +
								'<input type="hidden" name="lote_atual" value="1" />' + 
							'</div>' + 
							
						'</div>';
						
		$dialog = $(html_dialog);
		$lotes.clone().prependTo( $dialog.find('#infoLotes') );
		
		var title 	   = 'Lote 1 de '+ $lotes.length +' &nbsp; - &nbsp;' + $lotes.filter(':eq(0)').val();
		var buttonText = "Próximo Lote";
		
		if ($lotes.length == 1)
			buttonText = "Concluir...";
					
		$dialog.dialog({
			width: 950,
			height: 580,
			modal: true,
			title: title,
			buttons:
			[
				{
					text: buttonText,
					click: function() { 
						/*$(this).dialog("close");*/ 
						acaoConfirmaLote( $(this) );
						
					}
				}
			]
		})
		.css('font-size', '15px !important;')
		.bind({
			
			dialogbeforeclose: function(event, ui) {
		  
			  event.preventDefault();
			  jAlert('Conclua o preenchimento das questões <br>para fechar a janela.','Atenção.');
			  
			}
		});
		
	}
	
	function acaoConfirmaLote($dialog)
	{
		$lotes 	     = $dialog.find('#infoLotes').find('input[type="text"]').filter('.alternativa');
		$loteAtual   = $dialog.find('#infoLotes').find('input[name="lote_atual"]');
		numLoteAtual = parseInt($loteAtual.val());
		
		if (numLoteAtual == $lotes.length)
		{
			$dialog.remove();
		} else
		{
			numLoteAtual += 1;
			$loteAtual.val( numLoteAtual );
			
			var title 	   = 'Lote '+ numLoteAtual +' de '+ $lotes.length +' &nbsp; - &nbsp;' + 
							 $lotes.filter(':eq('+ (numLoteAtual-1) +')').val();
			var buttonText = "Próximo Lote";
			
			if (numLoteAtual == $lotes.length)
				buttonText = "Concluir...";
				
			$dialog.dialog("option", "title", title);
			$dialog.dialog({ buttons: 
							[
								{
									text: buttonText,
									click: function() { 
										acaoConfirmaLote( $(this) );
									}
								}
							] 
							});
							
			$dialog.find('.container_perg').find('input, select').val('');
			$dialog.find('.container_perg:first-child').find('input').focus();
		}
		
	}
	
	function verificaAcao($elemento) 
	{
		var acao = "";
		var classAltern = $elemento.attr('class');  // se tiver ação retornará algo como: 'acao_seM[Q]'
		
		if ( (classAltern != undefined) && (classAltern != "") )
		{
			
			posStart = classAltern.indexOf('[') + 1;
			posEnd   = classAltern.indexOf(']');
			
			if (posStart > 0 && posEnd > 0)
			{
				acao = classAltern.slice(posStart, posEnd); // Retornará algo como: Q, S, PROX_Q, PROX_S, PROX_R, MSG e DE_ATE.
			}
		}
		
		return acao;
	}
	
	
	/***************************************************************************
	 * Função: getJson
	 *
	 * Descrição: Realiza uma consultados de acordo com os parâmetros informados e 
	 *			  tendo como retorno um objeto JSON. Após o sucesso da funlçao AJAX,
	 *			  chama a funlçao passada por parâmetro "funcSeccess" passando o 
	 * 			  objeto json e o array "paramsFunc".
	 *
	 * IMPORTANTE: os nomes dos campos do Json são iguais aos do banco de dados.
	 *
	 * Parâmetros: 	reference    - Pode ser um consulta SQL completa ou 
	 *						   	   o nome de uma tabela Principal.
	 *				type	     - Tipo da "reference". Pode ser "query"
	 *							   ou "tabela"
	 *				codigo       - Código a ser consultado. Utilizado somente
	 *							   quando o type é igual "tabela"
	 *				jsonObjName  - Nome do Json retornado
	 *				functionName - Nome da função que chamou esta, para que seja 
	 *							   passado para a variável "currentCallAjax"
	 *				funcSuccess  - Função a ser executada após os sucesso do método
	 *							   AJAX.
	 *				paramsFunc   - Array de parâmetros passados para "funcSuccess" 
	 *							   além do ojeto JSON.
	 *
	 * Autor: Alexandre Varizi Ribeiro
	 * Data: 30/06/12
	 ***************************************************************************/
	function getJson(reference, type, codigo, jsonObjName, functionName, funcSuccess, paramsFunc) 
	{
		var params;
		
		switch (type.toLowerCase())
		{
			case "query":
			
				params = {
						query 		: reference,
						jsonObjName	: jsonObjName,
				     };
			break;
			
			case "tabela":
			
				params = {
						tabelaPrincipal	: reference, 
						jsonObjName		: jsonObjName,
						codigo			: codigo
				     };
			break;
			
		}
		
		var jsonRetorno = null;
		var url 		= '/pesquisacampo/manip_dados/jsonGeral.php';
		
		$.ajax({
			url: url,
			data: params,
			type: "POST",
			dataType: "json",
			timeout: 300000, // 5 minutos
			cache: false,
			beforeSend: function() { 
				currentCallAjax = functionName; 
			},
			success: function( data ) {
				
				funcSuccess(data, paramsFunc);
			}
		});
	}
	
	
/* ATRIBUIÇÕES GERAIS
----------------------------------------------------------*/	

	/* Variável global que recebe 'true' todas as vezes que
	 * a função 'executaAcao' é chamada e 'false' após a 
	 * execução dos comandos da função 'pergAtiva'
	 */
	var chamouAcao_Altern = false;
	
	/* Variável global para armazenar o método corrente
	 * que chamou um método AJAX ($.ajax)
	 */
	var currentCallAjax = "";
	
	
	estiliza();
	trataVariasResp();
	agrupaPergs();
	
	
/* EVENTOS 
----------------------------------------------------------*/	
	$('input[type="radio"]').live('change', function() {
		
		acao = verificaAcao( $(this) );
		if (acao != "")
		{
			executaAcao(acao, $(this));
		}
		
	});
	
	
	$('input[type="text"]').live('focusout', function() {
		
		acao = verificaAcao( $(this) );
		if (acao != "")
		{
			executaAcao(acao, $(this));
		}
		
	});
	

	$('.container_altern').find('input').live({
			focusin: function() {
				pergAtiva( $(this) );
			},
			
			click: function() {
				pergAtiva( $(this) );
			}
	});

});